package github.sf.fw.tools.cmd;

import java.util.ArrayList;
import java.util.List;


/**
 * 创建kvm的virt-install命令
 * 尽管virt-install命令有着众多选项，但实际使用中，其必须提供的选项仅包括--name、--ram、
 * --disk（也可是--nodisks）及安装过程相关的选项。
 * 此外，有时还需要使用括--connect=CONNCT选项来指定连接至一个非默认的hypervisor
 *
 * @author zhoup
 */
public class VirtInstallCmd extends BaseCmd {
    private final String BASE_CMD = "virt-install";

    public VirtInstallCmd() {
        final List<CmdOption> options = new ArrayList<>();
        options.add(new CmdOption("name", "--name", CPC.BLANK, "-n NAME虚拟机名称"));
        options.add(new CmdOption("memory", "--ram", CPC.BLANK, "-r MEMORY 虚拟机内在大小，单位为MB"));
        options.add(new CmdOption("vcpus", "--vcpus", CPC.BLANK, "--vcpus=VCPUS[,maxvcpus=MAX][,sockets=#][,cores=#][,threads=#]：VCPU个数及相关配置"));
        options.add(new CmdOption("cpu", "--cpu", CPC.BLANK, "--cpu=CPU：CPU模式及特性，如coreduo等；可以使用qemu-kvm -cpu来获取支持的CPU模式"));
        options.add(new CmdOption("cdrom", "--cdrom", CPC.BLANK, " -c CDROM, --cdrom=CDROM：光盘安装介质；"));
        options.add(new CmdOption("location", "--location", CPC.BLANK, "-l LOCATION, --location=LOCATION：安装源URL，支持FTP、HTTP及NFS等，如ftp://172.16.0.1/pub"));
        options.add(new CmdOption("pxe", "--pxe", CPC.NONE, "基于PXE完成安装"));
        options.add(new CmdOption("livecd", "--livecd", CPC.NONE, "把光盘当作LiveCD"));
        options.add(new CmdOption("osType", "--os-type", CPC.BLANK, "DISTRO_TYPE：操作系统类型，如linux、unix或windows等"));
        options.add(new CmdOption("osVariant", "--os-variant", CPC.BLANK, "--os-variant=DISTRO_VARIANT：某类型操作系统的变体，如rhel5、fedora8等"));
        options.add(new CmdOption("extraArgs", "--extra-args", CPC.BLANK, " -x EXTRA, --extra-args=EXTRA：根据--location指定的方式安装GuestOS时，" + "用于传递给内核的额外选项，例如指定kickstart文件的位置，--extra-args \"ks=http://172.16.0.1/class.cfg\""));
        options.add(new CmdOption("boot", "--boot", CPC.BLANK, "指定安装过程完成后的配置选项，如指定引导设备次序、使用指定的而非安装的kernel/initrd来引导系统启动等例如：\n" + "\uF075   --boot  cdrom,hd,network：指定引导次序；  \n" + "\uF075   --boot kernel=KERNEL,initrd=INITRD,kernel_args=”console=/dev/ttyS0”：指定启动系统的内核及initrd文件"));

        options.add(new CmdOption("disk", "--disk", CPC.BLANK, "指定存储设备及其属性；格式为--disk /some/storage/path,opt1=val1，opt2=val2等；常用的选项有\n " + "device：设备类型，如cdrom、disk或floppy等，默认为disk；  \n" + "\uF075   bus：磁盘总结类型，其值可以为ide、scsi、usb、virtio或xen；  \n" + "\uF075   perms：访问权限，如rw、ro或sh（共享的可读写），默认为rw；  \n" + "\uF075   size：新建磁盘映像的大小，单位为GB；  \n" + "\uF075   cache：缓存模型，其值有none、writethrouth（缓存读）及writeback（缓存读写）；  \n" + "\uF075   format：磁盘映像格式，如raw、qcow2、vmdk等；  \n" + "\uF075   sparse：磁盘映像使用稀疏格式，即不立即分配指定大小的空间"));
        options.add(new CmdOption("nodisks", "--nodisks", CPC.NONE, "--nodisks：不使用本地磁盘，在LiveCD模式中常用；"));
        options.add(new CmdOption("network", "--network ", CPC.BLANK, "--network NETWORK,opt1=val1,opt2=val2：将虚拟机连入宿主机的网络中，其中NETWORK可以为\n" + "bridge=BRIDGE：连接至名为“BRIDEG”的桥设备；  \n" + "\uF075   network=NAME：连接至名为“NAME”的网络"));
        options.add(new CmdOption("autoStart", "--autostart", CPC.NONE, "指定虚拟机是否在物理启动后自动启动"));
        options.add(new CmdOption("printXml", "--print-xml", CPC.NONE, "如果虚拟机不需要安装过程(--import、--boot)，则显示生成的XML而不是创建此虚拟机；默认情况下，此选项仍会创建磁盘映像"));
        options.add(new CmdOption("dryRun", "--dry-run", CPC.NONE, "执行创建虚拟机的整个过程，但不真正创建虚拟机、改变主机上的设备配置信息及将其创建的需求通知给libvirt"));
        options.add(new CmdOption("virtType", "--virt-type", CPC.BLANK, "使用的hypervisor，如kvm、qemu、xen等；所有可用值可以使用’virsh capabilities’命令获取"));
        options.add(new CmdOption("connect", "--connect", CPC.BLANK, "--connect qemu:///system"));
        options.add(new CmdOption("graphics ", "--graphics ", CPC.BLANK, "--graphics TYPE,opt1=val1,opt2=val2：指定图形显示相关的配置，此选项不会配置任何显示硬件（如显卡），而是仅指定虚拟机启动后对其进行访问的接口"));

        options.forEach(co -> {
            nameAndOption.put(co.getName(), co);
        });
    }

    @Override
    public String getCommand() {
        return BASE_CMD;
    }
}
